<?php
namespace app\api\service;

use app\adminapiv3\service\ServerAuth;
use app\common\service;
class Register extends Base
{

    public $host_id = 0;//主机id
    public $user_group = array();//用户组信息
    public $auth_info = array();//用户组授权信息
    public $hostkey = '';//hostkey
    /*
     * @name: 注册
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-11-07 11:27:25
     */
    function reg ($registerData)
    {
        //1. 判断是否是重新注册 ->判断依据是根据hostkey来判断

        $this->createHostKey($registerData);

        $this->checkRepeatRegster($registerData);

        if ($this->host_id == 0)
        {//初次注册

            //检查主机
            $this->checkHost($registerData);

            $this->dataInit($registerData);

        }else{//重新注册

            $this->addIpsConfig($registerData);

            $this->modifyHostInfo($registerData);//修改主机信息
        }
    }


    /**
     * @name: 生成主机码
     * @Param:
     * @Description:
     * @Author: foo
     * @Date: 2019-11-07 13:46:03
     */
    function createHostKey ($data)
    {
        $hostKeyStr = '';

        //遍历主机信息
        foreach ($data['host_info'] as $k => $v){
            $hostKeyStr .= $v;
        }


        if(empty($hostKeyStr)){
            $this->jsonErrOut('注册时失败:需要发送必要主机信息');
        }

        $hostKey = md5($hostKeyStr);
        $this->hostkey = $hostKey;
    }


    /**
     * @name: 检测是否重新注册
     * @Param:
     * @Description:
     * @Author: foo
     * @Date: 2019-11-06 17:24:22
     */
    function checkRepeatRegster ($data)
    {
        $return = 0;

        if (!isset($data['ipaddr']) || empty($data['ipaddr']))
        {
            $this->setError($this->CODE_FAIL, '注册时失败:需要发送IP地址信息');
            return $return;
        }


        $hostInfo = db('host')->where('key', $this->hostkey)->find();

        if (!empty($hostInfo)) {
            $this->host_id = $hostInfo['id'];
        }
    }


    /**
     * @name: 修改主机信息
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2019-11-07 13:52:55
     */
    function modifyHostInfo ($registerData)
    {

        $os = stristr($registerData['os'], 'windows') ? 2 : 1 ;

        $hostUpdateData = [
            'description' => '',//描述
            'name' => $registerData['alias'] . '(' . $registerData['ipaddr'] . ')',//主机名
            'os' => $os,
            'system_name' => $registerData['os'],//系统名
            'ip' => $registerData['ipaddr'],//主机IP
            'hardware_used' => json_encode($registerData['hardware']),//硬件使用情况
            'ctime' => time(),//创建时间
            'key' => $this->hostkey,//主机码
            'is_software' =>  isset($registerData['is_software']) ? 1 : 0,// 软件版出现该值
            'osversion' =>  isset($registerData['osversion']) ? $registerData['osversion'] : '',// 系统版本
        ];

        db('host')->where('id', $this->host_id)->update($hostUpdateData);
    }




    /**
     * @name 检查主机
     * @param $data
     * @author wx
     * @date 2020/6/12 15:12
     */
    function checkHost($data)
    {
        //检查主机码
        $userGroup = db('server_user_group')->where('bind_key', $data['bind_key'])->find();

        if(empty($userGroup)){
            $this->jsonErrOut('未找到该用户组');
        }

        //检查授权个数
        $moduleId = db('server_auth_module')->where('module_key', 'client')->value('id');
        if(!$moduleId){
            $this->jsonErrOut('当前用户组client模块未授权');
        }

        $server = new service\ServerUserGroupModule();
        $authInfo = $server->findData($userGroup['id'], $moduleId);

        if(!$authInfo){
            $this->jsonErrOut('当前用户组未授权');
        }

        if($authInfo['total'] <= $authInfo['used']){
            $this->jsonErrOut('该用户组授权数已满');
        }

        $authServer = new ServerAuth();
        $systemTime = $authServer->getSystemTime();

        //检查授权时间
        if($systemTime >= $authInfo['etime'] && $authInfo['etime'] != 0 ){
            $this->jsonErrOut('该用户组授权时间已过期');
        }

        $this->user_group = $userGroup;
        $this->auth_info = $authInfo;

    }

    /**
     * @name 主机数据初始化
     * @author wx
     * @date 2020/6/12 15:40
     */
    function dataInit($registerData)
    {
        $this->addHost($registerData);

        //检查授权
        $this->addModuleRelation();
        $this->addHostHardware($registerData);
        $this->addIpsConfig($registerData);
        $this->addHostStatus();
        $this->addRuleGroup();
        $this->addRule();
        $this->addFileScan();
        $this->addHostLink();

        //$this->addGroupUsed();
    }

    /**
     * @name 添加资产
     * @param $registerData
     * @author wx
     * @date 2020/6/12 16:01
     */
    function addHost($registerData)
    {
        $os = stristr($registerData['os'], 'windows') ? 2 : 1 ;

        $hostInsertData = [
            'group_id' => $this->user_group['id'],//主机归属用户组
            'description' => '',//描述
            'name' => $registerData['alias'] . '(' . $registerData['ipaddr'] . ')',//主机名
            'os' => $os,
            'system_name' => $registerData['os'],//系统名
            'ip' => $registerData['ipaddr'],//主机IP
            'hardware_used' => json_encode($registerData['hardware']),//硬件使用情况
            'ctime' => time(),//创建时间
            'key' => $this->hostkey,//主机码
            'is_software' =>  isset($registerData['is_software']) ? $registerData['is_software'] : 1,// 软件版出现该值
            'osversion' =>  isset($registerData['osversion']) ? $registerData['osversion'] : '',//系统版本
            'client_version' =>  isset($registerData['version']) ? $registerData['version'] : '3.0.0',//客户端版本
        ];

        $this->host_id = db('host')->insertGetId($hostInsertData);
    }

    /**
     * @name 添加机器信息
     * @param $registerData
     * @author wx
     * @date 2020/6/22 10:41
     */
    function addHostHardware($registerData)
    {
        $addHostHardwareData = array(
            'host_id' => $this->host_id,
            'info' => json_encode($registerData['hardware'])
        );
        db('host_hardware')->insert($addHostHardwareData);
    }

    /**
     * @name 添加ipsconfig配置
     * @author wx
     * @date 2020/6/22 12:58
     */
    function addIpsConfig($registerData)
    {
        $os = stristr($registerData['os'], 'windows') ? 2 : 1;

        if($os == 2){//windows
            $protect_ip = $registerData['ipaddr'];
            $device_ip = isset(explode(',', $registerData['ipaddr'])[0]) ? explode(',', $registerData['ipaddr'])[0] : '';
        }else{//linux

            $protect_ip = $registerData['ipaddr'];

            if($registerData['is_software'] == 0){//若客户端为硬件时,保护IP为下面的情况
                $protect_ip = '192.168.0.0/16,10.0.0.0/8,172.16.0.0/12';
            }

            $device_ip = isset($registerData['networkname'][0]) ? $registerData['networkname'][0] : '';
        }

        $addIpsConfigData = array(
            'protect_ip' => $protect_ip,
            'device_ip' => $device_ip,
            'host_id' => $this->host_id,
            'ctime' => time(),
        );

        db('ips_config')->insert($addIpsConfigData);
    }



    /**
     * @name 添加主机开关
     * @author wx
     * @date 2020/6/12 16:02
     */
    function addHostStatus ()
    {
        $hostStatus = [
            'host_id' => $this->host_id,//主机id
            'auto_defense' => 1,//主动防御
            'shell_defense' => 1,//脚本防御
            'shell_defense_handle' => 1,//脚本防御处理模式
            'shell_defense_level' => 2,//脚本防御级别
            'illegal_modify' => 1,//防篡改
            'file_safe' => 1,//畸形文件保护
            'empowerment' => 1,//提权
        ];

        db('HostStatus')->insert($hostStatus);
    }

    /**
     * @name 添加规则组
     * @author wx
     * @date 2020/6/12 16:04
     */
    function addRuleGroup ()
    {
        $HNRGR = new service\HostNormalRuleGroupRelation();
        $HNRGR->init($this->host_id);
    }

    /**
     * @name 添加规则
     * @author wx
     * @date 2020/6/12 16:04
     */
    function addRule ()
    {
        $HNRR = new service\HostNormalRuleRelation();
        $HNRR->init($this->host_id);
    }


    /**
     * @name 添加文件查杀
     * @author wx
     * @date 2020/6/12 16:04
     */
    function addFileScan ()
    {
        $fileScan = [
            'host_id' => $this->host_id,
        ];
        db('HostFileScreening')->insert($fileScan);
    }

    /**
     * @name 添加模块授权关系
     * @author wx
     * @date 2020/6/12 17:24
     */
    function addModuleRelation()
    {
        //查询所有授权模块
        $moduleList = db('server_auth_module')->column('module_key', 'id');

        //查询当前用户组授权模块
        $userGroupList = db('server_user_group_module')
            ->where('group_id', $this->user_group['id'])
            ->column('id, module_id, total, used, etime', 'module_id');

        $systemTimeServer = new ServerAuth();
        $systemTime = $systemTimeServer->getSystemTime();//系统时间

        //验证授权模块
        foreach ($moduleList as $moduleId => $moduleKey){
            if(isset($userGroupList[$moduleId])){
                $moduleInfo = $userGroupList[$moduleId];

                if ($moduleInfo['total'] > $moduleInfo['used']) {//授权数量够used才加1

                    if ($moduleInfo['etime'] != 0 && $systemTime < $moduleInfo['etime']) {//非永久授权
                        $insertData[$moduleKey] = 1;
                    }
                    if($moduleInfo['etime'] == 0){//永久授权
                        $insertData[$moduleKey] = 1;
                    }
                    //使用数量都加1
                    db('server_user_group_module')->where('id', $moduleInfo['id'])->setInc('used', 1);
                }

            }
        }

        $insertData['host_id'] = $this->host_id;

        db('host_module_relation')->insert($insertData);

    }

    /**
     * @name 添加连接
     * @author wx
     * @date 2020/8/27 10:47
     */
    function addHostLink()
    {
        $proxyInfo = db('server_proxy')->where('type', 'proxy')->find();

        if(!$proxyInfo){
            return 0;
        }

        $insertData['host_id'] = $this->host_id;
        $insertData['module'] = 'client';
        $insertData['port'] = $proxyInfo['port'];
        $insertData['ip'] = $proxyInfo['ip'];
        $insertData['status'] = 0;
        $insertData['version'] = '';

        db('host_link')->insert($insertData);
    }

    /**
     * 修改所属用户组使用数
     */
    private function addGroupUsed()
    {
        db('server_user_group_module')
            ->where('id', $this->auth_info['id'])
            ->setInc('used', 1);
    }

}